package auctionServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import auctionServer.utilities.Auction;
import auctionServer.utilities.GroupBid;
import auctionServer.utilities.User;


public class Server implements Runnable{
	private static int tcpPort;
	private static String analyticsServerBindingName;
	private static String billingServerBindingName;
	private static ServerSocket serverSocket;
	private static String serverKeyFile;
	private static String clientsKeyDir;
	
	private static Hashtable<String, User> logged;
	private static Vector<Auction> auctions;
	private static BufferedReader reader;
	public static List<GroupBid> groupBids;

	
	private  ExecutorService pool= Executors.newCachedThreadPool();
	private  Notifier notifier;
	
	
	public Server (int tcpPort, String analyticsServerBindingName, String billingServerBindingName, String serverKeyFile, String clientsKeyDir, BufferedReader reader) {
		Server.tcpPort=tcpPort;
		Server.analyticsServerBindingName=analyticsServerBindingName;
		Server.billingServerBindingName=billingServerBindingName;
		Server.logged=new Hashtable<String, User>();
		Server.auctions=new Vector<Auction>();
		Server.serverKeyFile=serverKeyFile;
		Server.clientsKeyDir=clientsKeyDir;
		Server.reader = reader;
		Server.groupBids = new ArrayList<GroupBid>();
	}
	public  void run(){
		notifier=new Notifier(auctions, analyticsServerBindingName, billingServerBindingName);
		Thread notifierThread=new Thread(notifier);
		notifierThread.start();
		 try {
	            serverSocket = new ServerSocket(tcpPort);
	            System.out.println("Auction server is ready");
		 } catch (IOException e) {
	            System.out.println("Could not listen on port: "+tcpPort);
	     }     
	       
		 try {
	     	while(true){
	        	//Jede einkommende Verbindung wird in eigenes Thread behandelt
	            pool.execute(new ServerReplica(tcpPort, serverSocket.accept(), logged,auctions, analyticsServerBindingName, serverKeyFile, clientsKeyDir, reader, groupBids));
	     	}
		 } catch (IOException e) {
	     	System.out.println("Server closed Accept failed: "+tcpPort);
		 }
	    
	}
	protected void close() throws IOException{
		pool.shutdown();
	    serverSocket.close();
	}
	
	public synchronized static String getClientList(){
		String message="";
		Enumeration<String> enumKey = logged.keys();
		while(enumKey.hasMoreElements()) {
		    String key = enumKey.nextElement();
		    User val = logged.get(key);
		    if(val.getValue()){
			    message+=val.getTCPPort()+" "+val.getName();

		    }
		    if(enumKey.hasMoreElements()) message+="\n";
		}
		return message;
	}
}

